#ifndef __QUERY_H__
#define __QUERY_H__
#include "Settings.h"

struct Query
{
public:
	char * queryName;
	char * query;
	~Query()
	{
		delete[] queryName;
		delete[] query;
	}
};

struct PausedQuery
{
	unsigned int queryId;
	short queryPos;
	char mismatchCount;
	unsigned int start, end, revStart, revEnd;
	bool direction;			//search direction
};


struct UnpackedQuery
{
	unsigned int queryId;
	char mismatchCount;
	short misPos[MAX_MISMATCH_NUM];
	char misBase[MAX_MISMATCH_NUM];
};

/*
void SetPausedQuery(PausedQuery *paused, unsigned int misCount, unsigned int id,unsigned int pos, 
					bool mdirection, unsigned int mrevStart, unsigned int mrevEnd,
					unsigned int mstart, unsigned int mend);
void SetUnpackedQuery(UnpackedQuery *unpacked, char misCount,unsigned int queryId, short *misPos,char *misBase);
void CopyPausedQuery(PausedQuery *paused, PausedQuery * temp);
*/
//void printPausedQuery(FILE * fout, PausedQuery * temp);
//void printUnpackedQuery(FILE * fout, UnpackedQuery * temp);
inline
unsigned int getQuerySizeInWord(unsigned int queryLen)
{
        return (queryLen + CHAR_PER_WORD - 1) / CHAR_PER_WORD;
}
inline
void printPausedQuery(FILE * fout, PausedQuery * temp)
{
        fprintf(fout,"%u\t%u\t%c\t%u\t%u\t%u\t%u\n",temp->queryId, temp->queryPos, temp->mismatchCount, temp->start, temp->end,
                temp->revStart, temp->revEnd);
}
inline
void printUnpackedQuery(FILE * fout, UnpackedQuery * temp)
{
        int i=0;
        fprintf(fout, "%d\t%c\n", temp->queryId, temp->mismatchCount);
        for(i=0; i<temp->mismatchCount; i++)
                fprintf(fout, "%d\t%c\n", temp->misPos[i], temp->misBase[i]);
}
/*
static
char * PackQuery(char * query, int queryLen)
{
	int i;
	char * packedQuery = new char[queryLen + 1];
	for(i=0; i<queryLen; i++)
	{
		switch(query[i])
		{
		case'A':
			packedQuery[i] = 0;
			break;
		case'C':
			packedQuery[i] = 1;
			break;
		case'G':
			packedQuery[i] = 2;
			break;
		case'T':
			packedQuery[i] = 3;
			break;
		}
	}
	packedQuery[i] = '\0';
	return packedQuery;
}
static
char * UnPackQuery(char * packedQuery, int queryLen)
{
	int i;
	char * query = new char[queryLen + 1];
	for(i=0; i<queryLen; i++)
	{
		switch(packedQuery[i])
		{
		case 0 :
			query[i] = 'A';
			break;
		case 1:
			query[i] = 'C';
			break;
		case 2:
			query[i] = 'G';
			break;
		case 3:
			query[i] = 'T';
			break;
		}
	}
	query[i] = '\0';
	return query;
}
*/

/*
inline
bool BackwardSearch(BWT *bwt, char* packedQuery, unsigned int lower, unsigned int upper, unsigned int * temp_start, unsigned int * temp_end)
{
	int i;

	if(*temp_start > *temp_end)
		return false;

	for (i= (int)(upper-1); i>= (int)lower; i--)
	{
		if(bwt->bwtCalc(packedQuery[i],temp_start, temp_end)== false)
			return false;
	}
	return true;
}


static 
bool ForwardSearch(BWT* revbwt, char* packedQuery, unsigned int lower, unsigned int upper, unsigned int *temp_rev_start, unsigned int *temp_rev_end, unsigned int *temp_start, unsigned int* temp_end)
{
	char c;
	unsigned int occCount[ALPHABET_SIZE];
	unsigned int occCount_start[ALPHABET_SIZE];
	unsigned int occCount_end[ALPHABET_SIZE];
	unsigned int i;
	int k;

	for (i=lower; i<upper && *temp_start<= *temp_end; i++)
	{
		c = packedQuery[i];

		revbwt->getAllOccValue(*temp_rev_start,occCount_start);
		revbwt->getAllOccValue(*temp_rev_end + 1,occCount_end);

		revbwt->bwtCalcWithOccValue(c,occCount_start[c], occCount_end[c], temp_rev_start, temp_rev_end);

		occCount[ALPHABET_SIZE-1] = 0;
		for(k=ALPHABET_SIZE-2; k>=0; k--)
		{
			occCount[k] = occCount[k+1] + occCount_end[k+1] - occCount_start[k+1];
		}

		*temp_end = *temp_end - occCount[c];
		*temp_start = *temp_end - (*temp_rev_end - *temp_rev_start);
	}
	if (*temp_start <= *temp_end && *temp_start > 0)
		return true;
	return false;
}
*/
#endif
